perm filename WLDMOD.SA1[HAL,HE] blob
sn#184248 filedate 1975-10-31 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00020 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00003 00002
C00004 00003 SIMPLE PROCEDURE STITINI
C00005 00004 ! fluent_fact
C00006 00005 ! affixed_to
C00007 00006 ! csplit, stmchk, is_undef_sym_item
C00008 00007 ! world assignment: xxxwld, wldasg (lpbasg, parasg)
C00014 00008 ! check_guards
C00015 00009 ! mergein
C00016 00010 ! cpattl
C00018 00011 ! asrtit & denyit
C00021 00012 ! new_fluent, new_set_fluent, new_var, new_exprn, stmake, new_stmnt
C00024 00013 ! domove
C00026 00014 ! do_affix, do_affix_stmnt, do_detach
C00030 00015 ! blockdo & sttblk
C00032 00016 ! Cobdo
C00033 00017 ! loopbdo
C00034 00018 ! statement interpreter: stinterp (owdo, iwcopy)
C00040 00019 ! proc_form interpreter: apfrm, apfrm2
C00041 00020 ! test program
C00042 ENDMK
C⊗;
IFCR ¬DECLARATION(EXTENDED_COMPILATION) THENC
ENTRY;
BEGIN "WLDMOD"
IFCR ¬DECLARATION(CREFFING) THENC DEFINE CREFFING = FALSE;ENDC
IFCR ¬ CREFFING THENC
REQUIRE "HALREQ.HDR" SOURCE_FILE;
ENDC
DEFINE $$PRGID "[]" = ["WLDMOD"];
ENDC
REQUIRE 300 SYSTEM_PDL;
INTEGER STITRC;
RPTR(SPECVAL) VNEWTRANS;
PROCEDURE VNEWINI;
BEGIN
VNEWTRANS←NEW_RECORD(SPECVAL);
SPECVAL:TYPE[VNEWTRANS]←TRANS_DTYPE;
END;
REQUIRE VNEWINI INITIALIZATION;
SIMPLE PROCEDURE STITINI;
BEGIN
OUTSTR("
SET TRACE OPTIONS FOR STINTERP:
'1 -- print ""statement"" type
'2 -- print ""statement"" record
type in one fhq octal number:");
STITRC←CVO(INCHWL);
END;
! fluent_fact;
BOOLEAN PROCEDURE FLUENT_FACT(RPTR(FACT) F);
BEGIN
RANY PTN;
PTN←FACT:PATT[F];
IF RECLEN(PTN)≠2 THEN RETURN(FALSE);
START_CODE "FLFSTC"
LABEL XXX,XXX0;
SKIPE 1,PTN;
SKIPN 1,1(1);
JRST XXX;
TLC 1,REC_CODE;
TLNE 1,(PROCB+ARY2B+ITEMB+'3740);
JRST XXX0; ! false if first isn't ref(record);
HRRZ 1,(1); ! point at record;
HRRZ 1,(1); ! point at record type;
CAIN 1,FLUENT;
XXX0: TDZA 1,1;
MOVEI 1,1;
XXX: END;
END;
! affixed_to;
BOOLEAN RECPROC AFFIXED_TO(RPTR(VARIABLE) V1,V2;ITEMVAR WLD);
BEGIN
RPTR(VARIABLE) V3,BYV,RGF;RPTR(TRANS) T;
∀ | LPMATCH(WLD,\(AFFIXED,V1,∃ V3,∃ BYV,∃ T,∃ RGF) ) DO
BEGIN
IF V2=V3 THEN RETURN(TRUE);
IF AFFIXED_TO(V3,V2,WLD) THEN RETURN(TRUE);
END;
∀ | LPMATCH(WLD,\(AFFIXED,∃ V3,V1,∃ BYV,∃ T,RIGIDLY) ) DO
BEGIN
IF V2=V3 THEN RETURN(TRUE);
IF AFFIXED_TO(V3,V2,WLD) THEN RETURN(TRUE);
END;
RETURN(FALSE);
END;
! csplit, stmchk, is_undef_sym_item;
SIMPLE ITEMVAR PROCEDURE CSPLIT(ITEMVAR IW;BOOLEAN NEWFG(TRUE));
RETURN(IF NEWFG THEN NEWWLD ELSE IW);
! be sure S is a statement;
RPTR(STMNT) PROCEDURE STMCHK(RANY S);
RETURN(CHKREC(S,LOC(STMNT)));
! world assignment: xxxwld, wldasg (lpbasg, parasg);
SIMPLE ITEMVAR PROCEDURE XXXWLD(ITEMVAR INW;BOOLEAN CLANY(FALSE));
BEGIN
! Makes a copy of the input world and returns it. If CLANY
is TRUE, then the "clear" field of the new world is set to
ANY. Otherwise, it is copied from the old world.;
ITEMVAR OUW;
OUW←NEWWLD;
CLEAR[WLDINX(OUW)]←IF CLANY THEN ANY ELSE CLEAR[WLDINX(INW)];
COPY_ALERTS(INW,OUW);
RETURN(OUW);
END;
INTERNAL RECURSIVE PROCEDURE WLDASG(RPTR(STMNT) S;
ITEMVAR IW;REFERENCE ITEMVAR OW;REFERENCE BOOLEAN NFLAG);
BEGIN
! Assigns worlds to statements associated with the statement
S. If NFLAG is true, then something or other special
happens. (This flag is used to avoid assigning separate
worlds to successive assignment statements).
No longer makes the variable list for blocks.
;
LABEL XIT;
RANY SS;
INTEGER ST;
RCELL C;
BOOLEAN NF;
OWN INTEGER OFFST; INITIALIZE(OFFST ← '20);
! OFFST is used to generate variable offsets;
RECPROC LPBASG(RPTR(STMNT) SS);
BEGIN
! Handles the special case of a loop body;
ITEMVAR IWW,WW;
NF←TRUE;
IWW←XXXWLD(IW,TRUE);
WW←PREP_ALERT(IWW);
CLEAR[WLDINX(IWW)]←WW;
WLDASG(SS,IWW,OW,NF);
OW←XXXWLD(IW);
END;
RECPROC PARASG(RCELL C);
BEGIN
! CDRs down a list of statements that are meant to be
parallel in execution, doing the world assignments.
Assigns a world to the end as well;
WHILE C≠NULL_RECORD DO
BEGIN
NF←TRUE;
WLDASG(STMCHK(CELL:CAR[C]),XXXWLD(IW,TRUE),OW,NF);
C←CELL:CDR[C];
END;
OW←XXXWLD(IW);
END;
SS←STMNT:SEMANTICS[S];
ST←RECTYPE(SS);
STMNT:IW[S]←IW;
IF ST=0 THEN
BEGIN
OW←STMNT:OW[S]←IW;
RETURN;
END;
IF ST=LOC(ASSERT)∨ST=LOC(DENY) THEN
BEGIN
IF ASSERT:WLD[SS]≠ANY THEN
BEGIN
OW←IW;
END
ELSE
BEGIN
OW←IF NFLAG THEN XXXWLD(IW) ELSE IW;
ASSERT:WLD[SS]←OW;
NFLAG←FALSE;
END;
STMNT:OW[S]←OW;
RETURN;
END
ELSE IF ST=LOC(ASSIGNMENT)∨ST=LOC(GASSIGN) THEN
BEGIN
OW←STMNT:OW[S]←IF NFLAG THEN XXXWLD(IW) ELSE IW;
NFLAG←FALSE;
RETURN;
END
ELSE
NFLAG←TRUE;
NF←TRUE;
IF ST=LOC(BLOCK) THEN
BEGIN "blkasg"
RPTR(BLOCK) B;
B←SS;
C←BLOCK:CODE[B];
OW←IW;
WHILE C≠NULL_RECORD DO
BEGIN
SS←CELL:CAR[C];
ST←RECTYPE(SS);
IF ST=LOC(PVL)∨ST=LOC(DBD) THEN
BEGIN
END
ELSE IF ST=LOC(VARIABLE) THEN
BEGIN
END
ELSE IF ST=LOC(STMNT) THEN
BEGIN "sasa"
WLDASG(SS,OW,OW,NF);
END;
C←CELL:CDR[C];
END;
END
ELSE IF ST=LOC(COBLOCK) THEN
BEGIN
PARASG(COBLOCK:CODE[SS]);
END
ELSE IF ST=LOC(FORR) THEN
LPBASG(FORR:BODY[SS])
ELSE IF ST=LOC(WHIL) THEN
LPBASG(WHIL:BODY[SS])
ELSE IF ST=LOC(IFF) THEN
BEGIN
NF←TRUE;
WLDASG(IFF:THN[SS],XXXWLD(IW,TRUE),OW,NF);
NF←TRUE;
WLDASG(IFF:ELS[SS],XXXWLD(IW,TRUE),OW,NF);
OW←XXXWLD(IW);
END
ELSE IF ST=LOC(NW) THEN
BEGIN
NFLAG←FALSE;
OW←NW:WLD[SS];
IF OW=ANY THEN
OW←XXXWLD(IW)
ELSE
BEGIN
CLEAR[WLDINX(OW,-1)]←CLEAR[WLDINX(IW)];
COPY_ALERTS(IW,OW);
END;
END
ELSE IF ST=LOC(PROG) THEN
BEGIN
! **** Not sure what to do here with NFLAG & NF ****;
WLDASG(PROG:CODE[SS],XXXWLD(IW,TRUE),OW,NF);
END
ELSE
OW←XXXWLD(IW);
STMNT:OW[S]←OW;
XIT: END;
! check_guards;
PROCEDURE CHECK_GUARDS(ITEMVAR IW,OW);
BEGIN
RPTR(FACT) F;
INTEGER OWX;
ITEMVAR GW,WW;
∀ WW | ALERT_ORDER⊗IW≡WW DO
BEGIN
GW←GUARD[WLDINX(WW)];
IF GW=ANY THEN CONTINUE;
∀ | GEN_FACTS(F,GW) DO
BEGIN
IF ¬TSTWIX(F,OWX) THEN
BEGIN
$PRINT(CRLF&"WARNING: ",TTYALWAYS);
PRNREC(FACT:PATT[F],TTYALWAYS);
$PRINT(" WAS ASSUMED TO BE TRUE, BUT MAY NOT BE"
&CRLF,TTYALWAYS);
END;
END;
END;
END;
! mergein;
PROCEDURE MERGEIN(ITEMVAR IW,OW);
BEGIN
RPTR(FACT) F;
INTEGER IWX,OWX;
IWX←WLDINX(IW);OWX←WLDINX(OW);
∀ | GEN_FACTS(F,OW) DO
BEGIN
IF ¬TSTWIX(F,IWX)∧FLUENT_FACT(F) THEN
CLRWLD(F,OWX);
END;
∀ | GEN_FACTS(F,IW) DO
BEGIN
IF ¬TSTWIX(F,OWX)∧¬FLUENT_FACT(F) THEN
SETWLD(F,OWX);
END;
END;
! cpattl;
LIST PROCEDURE CPATTL(RCELL C;ITEMVAR WLD;REFERENCE RCELL BL);
BEGIN
RANY V;
ITEMVAR IV;
INTEGER VTYP;
LIST PL;
BL←NULL_RECORD;
PL←NIL;
WHILE C≠NULL_RECORD DO
BEGIN "CLOOP"
V←CELL:CAR[C];
VTYP←RECTYPE(V);
IF VTYP=LOC(NOMV) THEN
BEGIN
! fetch nominal value;
V←EVALEXPR(V,WLD);
END
ELSE IF VTYP=LOC(BINDV) THEN
BEGIN
BL←CONS(V,BL);
IV←\(BINDV:RESULT[V])[1];
∂(IV,INTEGER)←∂(IV,INTEGER) LOR BINDB;
! **** BECAUSE OF A SAIL LOSSAGE *****;
PL[∞+1]←IV;
CONTINUE "CLOOP";
END
ELSE IF VTYP≠LOC(VARIABLE) THEN
USERERR(1,1,"CPATTL DOESN'T EXPECT AN ELEMENT OF TYPE "
&CVRTS(VTYP));
PL←PL&\($ V);
C←CELL:CDR[C];
END;
RETURN(PL);
END;
! asrtit & denyit;
INTERNAL PROCEDURE ASRTIT(RPTR(AFACT,SFACT) F;ITEMVAR IW,OW);
BEGIN
RCELL CC;
IF RECTYPE(F)=LOC(AFACT) THEN
BEGIN
RPTR(EXPRN,VARIABLE) L;
L←AFACT:LEFT[F];
IF RECTYPE(L)≠LOC(VARIABLE)∨AFACT:RELN[F]≠0 THEN
BEGIN
$PRINT(CRLF,TTYYES);
HALPRN(F,TTYYES);
USERERR(1,1," asrtit given an afact it cannot handle"&crlf);
RETURN;
END
ELSE
CHANGE(L,EVALEXPR(AFACT:RIGHT[F],IW),OW);
END
ELSE IF RECTYPE(F)=LOC(SFACT) THEN
BEGIN "SASSERT"
LPASRT(OW,CPATTL(SFACT:PATT[F],IW,CC));
IF CC≠NULL_RECORD THEN
USERERR(1,1,"BINDING ASSERTIT??");
END
ELSE
USERERR(1,1,"ASRTIT CALLED WITH FUNNY FACT");
END;
INTERNAL PROCEDURE DENYIT(RPTR(SFACT,AFACT) F;ITEMVAR IW,OW);
BEGIN
RANY CC;
IF RECTYPE(F)=LOC(AFACT) THEN
BEGIN
RPTR(EXPRN,VARIABLE) L;
L←AFACT:LEFT[F];
IF RECTYPE(L)≠LOC(VARIABLE)∨AFACT:RELN[F]≠0 THEN
BEGIN
$PRINT(CRLF,TTYYES);
HALPRN(F,TTYYES);
USERERR(1,1," denyit given an afact it cannot handle"&crlf);
RETURN;
END
ELSE
BEGIN
IF EXPEQV(EVALEXPR(L,IW),EVALEXPR(AFACT:RIGHT[F],IW)) THEN
INVALIDATE(L,OW);
END;
END
ELSE IF RECTYPE(F)=LOC(SFACT) THEN
BEGIN "SDENY"
LPDENY(OW,CPATTL(SFACT:PATT[F],IW,CC));
IF CC≠NULL_RECORD THEN
USERERR(1,1," binding denyit?? ");
END
ELSE
USERERR(1,1,"DENYIT CALLED WITH FUNNY FACT");
END;
! new_fluent, new_set_fluent, new_var, new_exprn, stmake, new_stmnt;
INTERNAL RANY FRTEMP;
INTERNAL RPTR(FLUENT) PROCEDURE NEW_FLUENT;
BEGIN
! creates a new fluent record & sets up pointers;
RPTR(FLUENT) FL;
FL←NEW_RECORD(FLUENT);
FLUENT:RETRPATT[FL]←PATTBLK(\($ FL,BIND FRTEMP));
RETURN(FL);
END;
INTERNAL RPTR(SET_FLUENT) PROCEDURE NEW_SET_FLUENT;
BEGIN
RPTR(SET_FLUENT) SFL;
SFL←NEW_RECORD(SET_FLUENT);
SET_FLUENT:RETRPATT[SFL]←PATTBLK(\($ SFL,BIND FRTEMP));
RETURN(SFL);
END;
INTERNAL RPTR(VARIABLE) PROCEDURE NEW_VAR(RANY ITEMVAR IV;INTEGER DT);
BEGIN
RPTR(VARIABLE) VAR;
VAR←NEW_RECORD(VARIABLE);
VARIABLE:PLNVAL[VAR]←NEW_FLUENT;
VARIABLE:CALCS[VAR]←NEW_SET_FLUENT;
VARIABLE:DEPS[VAR]←NEW_SET_FLUENT;
VARIABLE:CHANGERS[VAR]←NEW_SET_FLUENT;
VARIABLE:NAME[VAR]←IV;
∂(IV)←VAR;
VARIABLE:DATATYPE[VAR]←DT;
RETURN(VAR);
END;
INTERNAL RPTR(EXPRN) PROCEDURE NEW_EXPRN(INTEGER DT,OP;RCELL ARGS);
BEGIN
RPTR(EXPRN) E;
E←NEW_RECORD(EXPRN);
EXPRN:DATATYPE[E]←DT;
EXPRN:OP[E]←OP;
EXPRN:ARGS[E]←ARGS;
RETURN(E);
END;
INTERNAL RPTR(STMNT) PROCEDURE STMAKE(RSSS SEM(NULL_RECORD));
BEGIN
RPTR(STMNT) S;
S←NEW_RECORD(STMNT);
STMNT:SEMANTICS[S]←SEM;
STMNT:ID[S]←NEW(S);
RETURN(S);
END;
INTERNAL RPTR(STMNT) PROCEDURE NEW_STMNT(ITEMVAR IW,OW; RSSS SEM);
BEGIN
RPTR(STMNT) S;
S←STMAKE(SEM);
STMNT:IW[S]←IW;
STMNT:OW[S]←OW;
RETURN(S);
END;
! domove;
RECURSIVE PROCEDURE DOMOVE(RPTR(STMNT) S);
BEGIN
RPTR(VARIABLE) F,A;
RCELL C;
RANY ONM;
RPTR(MOVE$) MS;
ITEMVAR IW,OW;
! this routine doesn't do the right thing in cases
where FRAME is not the controllable frame. Consult
with RF on what to do about all this. ;
IW←STMNT:IW[S];OW←STMNT:OW[S];
CPYWLD(IW,OW);
MS ← STMNT:SEMANTICS[S]; ! Added by RF;
CHANGE(MOVE$:WHAT[MS],EVALEXPR(MOVE$:DEST[MS],OW),OW);
C←MOVE$:CLAUSES[MS];
WHILE C≠NULL_RECORD DO
BEGIN
RANY ONST;
ONST←CELL:CAR[C]; C←CELL:CDR[C];
IF RECTYPE(ONST)≠LOCATION(CMON) THEN CONTINUE;
STINTERP(STMCHK(CMON:CONCLUSION[ONST]));
ANDWLD(STMNT:OW[ONST],OW,OW);
END;
END;
! do_affix, do_affix_stmnt, do_detach;
INTERNAL PROCEDURE DO_AFFIX(RVAR F1,F2,BV;REXPR AE;RVAR RGF;ITEMVAR IW,OW);
BEGIN
RANY ASTN;
RPTR(FACT) ITEMVAR FCTI;
RPTR(TRANS) T;
ITEMVAR IV;
CHANGE(BV,T←EVALEXPR(AE,IW),OW);
ASTN←PATTBLK(\($ AFFIXED,
$ F1,
$ F2,
$ BV,
$ T,
$ RGF) );
IF PMATCH(ANY,ASTN,TRUE) THEN
BEGIN
SETWLD(_FACT_,WLDINX(OW));
RETURN;
END;
FCTI←FACT:ID[ASRTPF(OW,ASTN)];
MAKE F1CALC⊗FCTI≡NEW(
ADDCALC(F1,NEW_EXPRN(FRAME_DTYPE,TFMUL_OP,LIST2(BV,F2)),OW));
IF RGF=RIGIDLY THEN
BEGIN
! f1 <= bv*f2 , f2 <= inv(bv)*f1;
MAKE F2CALC⊗FCTI≡NEW(
ADDCALC(F2,NEW_EXPRN(FRAME_DTYPE,TFMUL_OP,
LIST2(NEW_EXPRN(TRANS_DTYPE,TINVRT_OP,
CONS(BV,NULL_RECORD)),F1)),OW));
END
ELSE
BEGIN
! f1 <= bv*f2 ... when_changing f1 also do bv←(f2→new) ;
RPTR(ASSIGNMENT) ASG;
RPTR(STMNT) CHG;
ASG←NEW_RECORD(ASSIGNMENT);
ASSIGNMENT:VAR[ASG]←BV;
ASSIGNMENT:VAL[ASG]←NEW_EXPRN(TRANS_DTYPE,
FTOF_OP,
LIST2(F2,VNEWTRANS));
CHG←NEW_RECORD(STMNT);
STMNT:SEMANTICS[CHG]←ASG;
MAKE CHNGR⊗FCTI≡NEW(CHG); ! *** replace all this with relies-on;
PUT_SET_FLUENT(OW,VARIABLE:CHANGERS[F1],CHG);
END;
END;
PROCEDURE DO_AFFIX_STMNT(RSTMNT S);
BEGIN
ITEMVAR IW,OW;
RPTR(AFFIX) A;
REXPR AE;
RVAR BV,F1,F2;
IW←STMNT:IW[S];
OW←STMNT:OW[S];
CPYWLD(IW,OW);
A←STMNT:SEMANTICS[S];
F1←AFFIX:FRAME1[A];
F2←AFFIX:FRAME2[A];
BV←AFFIX:BYVAR[A];
IF BV=NULL_RECORD THEN
BEGIN
BV←NEW_VAR(NEW(NULL_RECORD),TRANS_DTYPE);
AFFIX:BYVAR[A]←BV;
NEW_PNAME(VARIABLE:NAME[BV],"VAR"&CVS(VARNO));
VARNO←VARNO+1;
END;
AE←AFFIX:ATEXP[A];
IF AE=NULL_RECORD THEN
AE←AFFIX:ATEXP[A]←NEW_EXPRN(TRANS_DTYPE,FTOF_OP,LIST2(F2,F1));
DO_AFFIX(F1,F2,BV,AE,AFFIX:RIGID[A],IW,OW);
END;
INTERNAL PROCEDURE DO_DETACH(RVAR F1,F2;ITEMVAR IW,OW);
BEGIN
RVAR BV,RGF;
RPTR(TRANS) T;
∀ | LPMATCH(IW,\($ AFFIXED,$ F1,$ F2,
BIND BV,
BIND T,
BIND RGF)) DO
BEGIN
RPTR(FACT) ITEMVAR FCTI;
RPTR(CALCULATOR,PROC_FORM) ITEMVAR CI;
FCTI←FACT:ID[_FACT_];
CLRWLD(_FACT_,WLDINX(OW));
IF CHNGR⊗FCTI≡BIND CI THEN
REM_SET_FLUENT(OW,VARIABLE:CHANGERS[F1],∂(CI));
IF F1CALC⊗FCTI≡BIND CI THEN
REM_SET_FLUENT(OW,VARIABLE:CALCS[F1],∂(CI));
IF F2CALC⊗FCTI≡BIND CI THEN
REM_SET_FLUENT(OW,VARIABLE:CALCS[F2],∂(CI));
END;
END;
! blockdo & sttblk;
RECPROC BLOCKDO(RPTR(STMNT) S);
BEGIN
ITEMVAR IW;
RCELL C;
C←BLOCK:CODE[STMNT:SEMANTICS[S]];
IW←STMNT:IW[S];
WHILE C≠NULL_RECORD DO
BEGIN
INTEGER ST;
ST←RECTYPE(CELL:CAR[C]);
IF ST=LOC(STMNT) THEN
BEGIN
STINTERP(CELL:CAR[C]);
IW←STMNT:OW[CELL:CAR[C]];
END
ELSE IF ST=LOC(PVL) THEN
PVLDO(PVL:VL[CELL:CAR[C]],IW)
ELSE IF ST=LOC(VARIABLE) THEN
BEGIN
END
ELSE IF ST=LOC(DBD) THEN
WLDDMP(DBD:WLD[CELL:CAR[C]])
ELSE IF ST=LOC(NW) THEN
BEGIN
END
ELSE
BEGIN
USERERR(1,1,"FUNNY BLOCK ELEMENT");
END;
C←CELL:CDR[C];
END;
END;
INTERNAL RPTR(BLOCK) PROCEDURE STTBLK(RANY S);
BEGIN
RPTR(BLOCK) B;
IF RECTYPE(S)≠LOC(BLOCK) THEN
BEGIN
B←NEW_RECORD(BLOCK);
BLOCK:CODE[B]←CONS(S,NULL_RECORD);
RETURN(STMAKE(B));
END;
RETURN(S);
END;
! Cobdo;
RECPROC COBDO(RPTR(STMNT) S);
BEGIN
RCELL C;
BOOLEAN FLAG;
RPTR(STMNT) SS;
C←COBLOCK:CODE[CHKREC(STMNT:SEMANTICS[S],LOC(COBLOCK))];
FLAG←FALSE;
WHILE C≠NULL_RECORD DO
BEGIN
SS←STMCHK(CELL:CAR[C]);
CPYWLD(STMNT:IW[S],STMNT:IW[SS]);
STINTERP(SS);
IF FLAG THEN
MERGEIN(STMNT:OW[SS],STMNT:OW[S])
ELSE
BEGIN
FLAG←TRUE;
CPYWLD(STMNT:OW[SS],STMNT:OW[S]);
END;
C←CELL:CDR[C];
END;
IF ¬FLAG THEN
CPYWLD(STMNT:IW[S],STMNT:OW[S]);
END;
! loopbdo;
RECPROC LOOPBDO(RPTR(STMNT) S);
BEGIN
CALL_ALERT(STMNT:IW[S]);
STINTERP(S);
CHECK_GUARDS(STMNT:IW[S],STMNT:OW[S]);
END;
! statement interpreter: stinterp (owdo, iwcopy);
INTERNAL RECPROC STINTERP(RPTR(STMNT) S);
BEGIN
! Takes the statement S and interprets what it would do to
the world. The worlds associated with S are actually
modified;
INTEGER STYP;
ITEMVAR IW,OW;
RSSS SS;
RPTR(STMNT) S1,S2;
PROCEDURE OWDO;
CPYWLD(IW,OW);
SIMPLE PROCEDURE IWCOPY(RPTR(STMNT) SX);
CPYWLD(IW,STMNT:IW[SX]);
IF STITRC LAND '1 THEN
$PRINT(CRLF&"STATEMENT TYPE ="&CVOS(STYP));
IF STITRC LAND '2 THEN
BEGIN
$PRINT(CRLF&"STATEMENT RECORD =");
HALPRN(S);
END;
IF S=NULL_RECORD THEN
RETURN;
IF RECTYPE(S) ≠ LOC(STMNT)
THEN BEGIN ! Added by RF;
USERERR(1,1,"STINTERP: Not a statement");
RETURN;
END;
IF ¬UNBOUND(STMNT:PRC[S]) THEN
BEGIN
DEFINE PREDICT_EFFECTS_REC "[]" = "RPEFCT";
EXTERNAL RANY PREDICT_EFFECTS_REC;
! defined in RHTREC;
REC_RESUME(STMNT:PRC[S],PREDICT_EFFECTS_REC);
RETURN;
END;
SS←STMNT:SEMANTICS[S];
IF SS=NULL_RECORD THEN RETURN;
STYP←RECTYPE(SS);
IW←STMNT:IW[S];
OW←STMNT:OW[S];
IF STYP=LOC(BLOCK) THEN
BLOCKDO(S)
ELSE IF STYP=LOC(ASSIGNMENT) THEN
BEGIN
OWDO;
CHANGE(ASSIGNMENT:VAR[SS],
EVALEXPR(ASSIGNMENT:VAL[SS],OW),OW);
! note that this is OW now (so side effects happen);
END
ELSE IF STYP=LOC(GASSIGN) THEN
BEGIN
OWDO;
INVALIDATE(GASSIGN:VAR[SS],OW);
CASE GASSIGN:OP[SS] OF
BEGIN
[1] ADDCALC(GASSIGN:VAR[SS],GASSIGN:EXP[SS],OW);
[2] KILLCALC(GASSIGN:VAR[SS],GASSIGN:EXP[SS],OW);
[3] ONLYCALC(GASSIGN:VAR[SS],GASSIGN:EXP[SS],OW);
[0] USERERR(1,1,"ILLEGAL GRAPH ASSIGNMENT OP")
END;
END
ELSE IF STYP=LOC(IFF) THEN
BEGIN
! here need code to handle conditional;
S1←STMCHK(IFF:THN[SS]);
S2←STMCHK(IFF:ELS[SS]);
IWCOPY(S1);
IWCOPY(S2);
STINTERP(S1);
STINTERP(S2);
ANDWLD(STMNT:OW[S1],STMNT:OW[S2],OW);
END
ELSE IF STYP=LOC(COBLOCK) THEN
BEGIN
COBDO(S);
END
ELSE IF STYP=LOC(WHIL) THEN
BEGIN
S1←STMCHK(WHIL:BODY[SS]);
IWCOPY(S1);
LOOPBDO(S1);
ANDWLD(STMNT:OW[S1],IW,OW);
END
ELSE IF STYP=LOC(FORR) THEN
BEGIN ! Added by RF;
S1←STMCHK(FORR:BODY[SS]);
IWCOPY(S1);
LOOPBDO(S1);
ANDWLD(STMNT:OW[S1],IW,OW);
END
ELSE IF STYP=LOC(ASSERT) THEN
BEGIN
OWDO;
ASRTIT(ASSERT:FACT[SS],IW,ASSERT:WLD[SS]);
END
ELSE IF STYP=LOC(DENY) THEN
BEGIN
OWDO;
DENYIT(DENY:FACT[SS],IW,DENY:WLD[SS]);
END
ELSE IF STYP=LOC(AFFIX) THEN
BEGIN
DO_AFFIX_STMNT(S);
END
ELSE IF STYP=LOC(NW) THEN
OWDO
ELSE IF STYP = LOC(MOVE$) THEN
BEGIN "move"
DOMOVE(S);
END "move"
ELSE IF STYP = LOC(COMMNT) THEN
BEGIN "commnt" ! Added by RF;
OWDO;
END "commnt"
ELSE IF STYP = LOC(ALSODO) THEN
BEGIN "alsodo" ! Added by RF;
OWDO; ! Temporarily does nothing;
END "alsodo"
ELSE IF STYP = LOC(CMON) THEN
BEGIN "cmon" ! Added by RF;
OWDO; ! Temporarily does nothing;
END "cmon"
ELSE IF STYP = LOC(EVDO) THEN
BEGIN "evdo" ! Added by RF;
OWDO; ! Temporarily does nothing;
END "evdo"
ELSE IF STYP = LOC(PROG) THEN ! added by RF;
STINTERP(PROG:CODE[SS])
ELSE
BEGIN
$PRINT(CRLF&"***");
HALPRN(SS);
USERERR(1,1," STINTERP GIVEN A STATEMENT TYPE IT CANNOT HANDLE");
END;
END;
! proc_form interpreter: apfrm, apfrm2;
INTERNAL RECPROC APFRM(RPTR(PROC_FORM) PF;RCELL VL);
BEGIN
RCELL PFFPL;
PFFPL←PROC_FORM:FPS[PF];
WHILE PFFPL≠NULL_RECORD ∧ VL≠NULL_RECORD DO
BEGIN
VCELL:VAL[CELL:CAR[PFFPL]]←CELL:CAR[VL];
PFFPL←CELL:CDR[PFFPL];
VL←CELL:CDR[VL];
END;
STINTERP(PROC_FORM:S[PF]);
END;
INTERNAL RECPROC APFRM2(RPTR(PROC_FORM) PF;RPTR(VALU$) V1,V2);
BEGIN
RCELL PFFPL;
RPTR(VALU$) V;
PFFPL←PROC_FORM:FPS[PF];
FOR V←V1,V2 DO
BEGIN
IF PFFPL=NULL_RECORD THEN DONE;
VCELL:VAL[CELL:CAR[PFFPL]]←V;
PFFPL←CELL:CDR[PFFPL];
END;
STINTERP(PROC_FORM:S[PF]);
END;
! test program;
IFCR TRUE THENC
INTERNAL PROCEDURE WMTEST;
WHILE TRUE DO
BEGIN
REQUIRE "GOBBLE.HDR[HAL,RHT]" SOURCE_FILE;
INTEGER NF;
RCELL SE;
RANY ST;
RPTR(STMNT) BS;
SE←READ;
ST←GROVEL(SE);
BS←STTBLK(ST);
NF←TRUE;
WLDASG(BS,CURWLD,CURWLD,NF);
HALPRN(BS);
$PRINT(CRLF);
STINTERP(BS);
END;
ENDC
END $$PRGID;